package xpn.platform.common.rulesengine;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

@Component
@Slf4j
/**
 * 简单规则引擎实现
 * 
 * @author bobatkm Oct 20, 2017
 *
 */
public class SimpleRulesEngineImpl implements SimpleRulesEngine {

	private static ScriptEngineManager scriptEngineMgr;
	private static ScriptEngine jsEngine;

	private SimpleBindings simpleBindings;

	// 获得JavaScript引擎
	static {
		scriptEngineMgr = new ScriptEngineManager();
		jsEngine = scriptEngineMgr.getEngineByName("JavaScript");
	}

	public SimpleRulesEngineImpl() {
		simpleBindings = new SimpleBindings();
	}

	@Override
	public boolean injectObjects(InjectedObject... objList) {
		for (InjectedObject var : objList) {
			simpleBindings.put(var.getRefVarName(), var.getObj());
		}
		return true;
	}

	@Override
	public boolean injectObjects(Object... objList) {
		for (Object obj : objList) {
			simpleBindings.put(obj.getClass().getSimpleName(), obj);
		}
		return true;
	}

	@Override
	public Object executeRule(String ruleExpression) {
		if (ruleExpression == null || "".equals(ruleExpression)) {
			return false;
		}

		try {
			return jsEngine.eval(ruleExpression, simpleBindings);
		} catch (ScriptException e) {
			log.error("SimpleRulesEngine：script exception!", e);
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public Boolean isTrue(String ruleExpression) throws ScriptException {
		Object ret = this.executeRule(ruleExpression);
		boolean isBoolean = ret instanceof Boolean;
		if (!isBoolean) { // 如果返回值不是bool型，则是规则配置错误，则忽略该规则
			return false;
		}
		return (Boolean) ret;
	}
}
